type nullable<T> = T|null
type nullable2<T, E> = T|E|null

fn main() {
    // nullable 测试
    nullable<i8> nat = null
    println(nat)
    nat = 6 as i8
    println(nat)

    // union 类型可以进行类型推导
    var foo = nat
    println(foo)

    // 更大范围的类型接收小范围 union 的类型
    nullable2<i8, i32> bar = nat
    println(bar)
    bar = 7 as i32

    // any 可以接收所有类型的值
    any baz = bar
    println(baz)

    // 重新赋值为 null
    baz = null
    println(baz)

    // 尝试基于类型断言进行数值运算
    println(nat as i8)
    i8 a = (nat as i8) + 2
    println(a)

    // 类型检查
    print(nat is i8, nat is null, nat is [i8], '\n')

    // 基于首个元素类型进行推断
    type i8_i16_list = [i8]|[i16]
    i8_i16_list b = [0 as i8]

    // 通过类型转换语法进行推断
    println((b as [i8]).len())

    // 空数组快速确定类型
    i8_i16_list c = vec_new<i8>(0, 0)
    var d = vec_new<i16>(0, 0)
    print((c as [i8]).len(), d.len(), '\n')
    c = d

    print(c is [i8], c is [i16], '\n')


    // rawptr
    rawptr<int> a1 = null
    int b1 = 12
    a1 = &b1
    println(a1 as anyptr == &b1 as anyptr)
}